#https://blog.csdn.net/zhuisui_woxin/article/details/84400439
import cv2
import os
import numpy as np
import FlannMatch
import VideoStream
import Mahjong

#import DetectCardsLib
from readconfig import ReadConfig
from ApiServer import HttpServer
from threading import Thread

def OpencvDetect(image):

    # Pre-process camera image (gray, blur, and threshold it)
    pre_proc = Mahjong.preprocess_image(image)
    #灰度处理
    #cv2.imshow("preprocess_image",pre_proc)
    #print('Press "c" to continue.')
    #key = cv2.waitKey(0) & 0xFF
    #if key == ord('c'):
    #    pass
    img,cnts, hier = cv2.findContours(pre_proc,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    index_sort = sorted(range(len(cnts)), key=lambda i : cv2.contourArea(cnts[i]),reverse=True)
    if len(cnts) == 0:
        return [], []
    cnts_sort = []
    hier_sort = []
    cnt_is_card = np.zeros(len(cnts),dtype=int)
    # Fill empty lists with sorted contour and sorted hierarchy. Now,
    # the indices of the contour list still correspond with those of
    # the hierarchy list. The hierarchy array can be used to check if
    # the contours have parents or not.
    for i in index_sort:
        cnts_sort.append(cnts[i])
        hier_sort.append(hier[0][i])
    CARD_MAX_AREA = 120000
    CARD_MIN_AREA = 15000
    # Determine which of the contours are cards by applying the
    # following criteria: 1) Smaller area than the maximum card size,
    # 2), bigger area than the minimum card size, 3) have no parents,
    # and 4) have four corners
    for i in range(len(cnts_sort)):
        size = cv2.contourArea(cnts_sort[i])
        peri = cv2.arcLength(cnts_sort[i],True)
        approx = cv2.approxPolyDP(cnts_sort[i],0.01*peri,True)
        if ((size < CARD_MAX_AREA) and (size > CARD_MIN_AREA) and (hier_sort[i][3] == -1) and (len(approx) >= 4)):
            print(f"{size},{len(approx)}")
            cnt_is_card[i] = 1
    
    return cnts_sort, cnt_is_card,pre_proc
if __name__ == '__main__':
    h_image=cv2.imread("1bing_7.jpg")
    # 找和排序轮廓
    cnts_sort, cnt_is_card,pre_proc =OpencvDetect(h_image)
    k = 0
    cards = []
    for i in range(len(cnts_sort)):
        if (cnt_is_card[i] == 1):
            # Create a card object from the contour and append it to the list of cards.
            # preprocess_card function takes the card contour and contour and
            # determines the cards properties (corner points, etc). It generates a
            # flattened 200x300 image of the card, and isolates the card's
            # suit and rank from the image.
            preprocess_card_obj=Mahjong.preprocess_card(cnts_sort[i],h_image)
            


            #根据轮廓获取区域
            x, y, w, h = cv2.boundingRect(preprocess_card_obj.contour)
            
            #截取矩形框内容
            newimage=h_image[y+2:y+h-2,x+2:x+w-2] # 先用y确定高，再用x确定宽
            #降噪（模糊处理用来减少瑕疵点）
            #result = cv2.blur(newimage, (5,5))
            result=cv2.medianBlur(newimage, 5)
            #灰度化,就是去色（类似老式照片）
            gray=cv2.cvtColor(result,cv2.COLOR_BGR2GRAY)
            #retval, gray =cv2.threshold(gray1, 0, 255, cv2.THRESH_OTSU)

            #param1的具体实现，用于边缘检测   
            #canny = cv2.Canny(img, 40, 80)  
            cv2.imshow('4',gray)
            print('Press "c" to continue.')
            key = cv2.waitKey(0) & 0xFF
            if key == ord('c'):
                pass

            
            #霍夫变换圆检测
            circles = cv2.HoughCircles(gray,cv2.HOUGH_GRADIENT,1,20,param1=80,param2=20,minRadius=15,maxRadius=20)
            if not circles is None:
                #获取到的区域画一个矩形框
                cv2.rectangle(h_image, (x,y), (x+w,y+h), (153,153,0), 5)
                cards.append(preprocess_card_obj)
                cards[k].result_value=len(circles[0])
                print('-------------我是条分割线-----------------')
                #根据检测到圆的信息，画出每一个圆
                for circle in circles[0]:
                    #圆的基本信息
                    print(circle[2])
                    #坐标行列(就是圆心)
                    x=int(circle[0])
                    y=int(circle[1])
                    #半径
                    r=int(circle[2])
                    #在原图用指定颜色圈出圆，参数设定为int所以圈画存在误差
                    img=cv2.circle(newimage,(x,y),r,(0,0,255),1,8,0)
                    #显示新图像
                #画上所有的园
                #cv2.imshow('5',img)
                # 把中心点与结果画到图片上
                h_image = Mahjong.draw_mahajong_results(h_image, cards[k])
                k = k + 1
            else:
                bb_count=FlannMatch.findbackgroud(gray,"./bb/")
                if(bb_count>0):
                    print("bb{}",bb_count)
                    #获取到的区域画一个矩形框
                    cv2.rectangle(h_image, (x,y), (x+w,y+h), (153,153,0), 5)
                    cards.append(preprocess_card_obj)
                    cards[k].result_value='bb'
                    h_image = Mahjong.draw_mahajong_results(h_image, cards[k])
                    k = k + 1
                else:
                    bb1_count=FlannMatch.findbackgroud(gray,"./1b/")
                    if(bb1_count>0):
                        print("1{}",bb1_count)
                        #获取到的区域画一个矩形框
                        cv2.rectangle(h_image, (x,y), (x+w,y+h), (153,153,0), 5)
                        cards.append(preprocess_card_obj)
                        cards[k].result_value='1'
                        h_image = Mahjong.draw_mahajong_results(h_image, cards[k])
                        k = k + 1
    if (len(cards) != 0):
            temp_cnts = []
            for i in range(len(cards)):
                    temp_cnts.append(cards[i].contour)
                    #cv2.imshow("newimage",newimage)
                    #print('Press "c" to continue.')
                    #key = cv2.waitKey(0) & 0xFF
                    #if key == ord('c'):
                    #    pass
            cv2.drawContours(h_image,temp_cnts, -1, (255,0,0), 2)

    cv2.imshow("preprocess_image",h_image)
    print('Press "c" to continue.')
    key = cv2.waitKey(0) & 0xFF
    if key == ord('c'):
        pass
    # Close all windows and close the PiCamera video stream.
    cv2.destroyAllWindows()
    #videostream.stop()
